package com.binary.coder.gift.core.config.async;

import com.google.common.collect.Queues;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.*;

/**
 * @author qinqin.luo.
 * @title 异步配置
 * @time 2022/6/20.
 */
@EnableAsync
@Configuration
@Slf4j
public class AsyncConfiguration {

    @Value("${async.max.core:40}")
    Integer asyncMaxCoreSize;

    @Value("${async.max.pool:80}")
    Integer asyncMaxPoolSize;

    @Bean
    public Executor asyncExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                asyncMaxCoreSize, asyncMaxPoolSize, 60, TimeUnit.SECONDS,
                Queues.newArrayBlockingQueue(300), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                r.run();
            }
        }
        );
        return threadPoolExecutor;
    }

    @Bean
    public Executor assayExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5, 10, 60, TimeUnit.SECONDS,
                Queues.newArrayBlockingQueue(300), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                r.run();
            }
        }
        );
        return threadPoolExecutor;
    }

    @Value("${dacoo.schedule.max.core:50}")
    Integer daccoScheduleMaxCoreSize;

    @Bean
    public ScheduledExecutorService dacooScheduledExecutorService(){
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor
                (daccoScheduleMaxCoreSize, (r,e) -> log.error("ScheduledExecutorService is full", e));
        return scheduledThreadPoolExecutor;
    }


    @Bean
    public Executor syncIngredientExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2, 8, 60, TimeUnit.SECONDS,
                Queues.newArrayBlockingQueue(50), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                r.run();
            }
        }
        );
        return threadPoolExecutor;
    }


    @Bean
    public Executor calculateNyActualCostExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2, 8, 60, TimeUnit.SECONDS,
                Queues.newArrayBlockingQueue(50), new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                r.run();
            }
        }
        );
        return threadPoolExecutor;
    }

}
